package org.wevil.filter;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.wevil.enumu.ResultEnum;
import org.wevil.util.JwtUtil;
import org.wevil.vo.Result;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 登录过滤器
 *
 * @author wanglei
 * @since 2020/12/17
 */
@Slf4j
@Component
@WebFilter(filterName = "loginFilter", urlPatterns = "/*")
public class LoginFilter implements Filter {

    public static final AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**忽略登录路径：系统*/
    private final String[] ignoreUrlSys = {
            "/druid/**", // druid
            "/test/**", // 测试
            "/rest/**", // 测试RestController
            "/login/**", "/register", // 登录/注册
            "/app/version", // 获取app版本
            "/swagger-ui/**", "/swagger-resources/**", "/v3/**", // swagger相关
            "/res/**", "/files/**", // 系统资源：图片
            "**/*.html", "**/*.jp*g", "**/*.png", "**/*.js", "**/*.css", "**/*.ico" // 文件后缀
    };

    /**忽略登录路径*/
    private final String[] ignoreUrlBusiness = {
           "/middleWare/*", "/NotificationInfo/KeepAlive", // 中间件
           "/paypal/**", // paypal
    };


    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 转换为HttpServletRequest
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 设置response
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        String token = request.getHeader("token");
        // 如果满足过滤规则，直接通过
        String requestURI = request.getRequestURI();
        if (isIgnore(requestURI)) {
            filterChain.doFilter(request, response);
        }
        // 否则判断token是否存在
        else if (token != null && !token.isEmpty()) {
            // 不报错就算验证通过
            try {
                JwtUtil.verifyToken(token);
            } catch (SignatureVerificationException | JWTDecodeException | IllegalArgumentException | TokenExpiredException e) {
                response.setStatus(401);
                response.getWriter().println(JSON.toJSON(Result.info(ResultEnum.Unauthorized)));
                return;
            }
            filterChain.doFilter(request, response);
        } else {
            response.setStatus(401);
            response.getWriter().println(JSON.toJSON(Result.info(ResultEnum.Unauthorized)));
        }
    }

    /**
     * 自定义过滤规则，哪些地址可以过去，哪些地址过不去
     *
     * @param requestURI 请求地址
     * @author wanglei
     * @since 2020/12/21
     * */
    public boolean isIgnore(String requestURI){
        for(String sysUrl : ignoreUrlSys){
            if(antPathMatcher.match(sysUrl, requestURI)){
                return true;
            }
        }
        for(String businessUrl : ignoreUrlBusiness){
            if(antPathMatcher.match(businessUrl, requestURI)){
                return true;
            }
        }
        return false;
    }

    @Override
    public void destroy() {
        log.info("LoginFilter 销毁");
    }
}
